package com.sixbro.websocket.netty.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.sixbro.websocket.netty.common.ChatConstants;
import com.sixbro.websocket.netty.module.Message;
import com.sixbro.websocket.netty.module.UserInfo;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author: Mr.Lu
 * @Date: 2020/9/19 15:11
 */
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    private static final Logger logger = LoggerFactory.getLogger(TextWebSocketFrameHandler.class);

    private final ChannelGroup group;

    public TextWebSocketFrameHandler(ChannelGroup group) {
        this.group = group;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        logger.info("Event====>{}", evt);

        if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
            ctx.pipeline().remove(HttpRequestHandler.class);

            //加入当前, 上线人员推送前端，显示用户列表中去
            Channel channel = ctx.channel();
            Message message = new Message(null, "");
            group.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message, SerializerFeature.DisableCircularReferenceDetect)));
            group.add(channel);
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        Channel channel = ctx.channel();
        String token = channel.attr(ChatConstants.CHANNEL_TOKEN_KEY).get();
        UserInfo from = ChatConstants.onlines.get(token);
        if (from == null) {
            group.writeAndFlush("OK");
        } else {
            Message message = new Message(from, msg.text());
            group.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message, SerializerFeature.DisableCircularReferenceDetect)));
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("Current channel channelInactive");
        offlines(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        logger.info("Current channel handlerRemoved");
        offlines(ctx);
    }

    private void offlines(ChannelHandlerContext ctx) {
        Channel channel = ctx.channel();
        String token = channel.attr(ChatConstants.CHANNEL_TOKEN_KEY).get();
        ChatConstants.removeOnlines(token);

        group.remove(channel);
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("=====> {}", cause.getMessage());
        offlines(ctx);
    }
}
